package com.xiaogao.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaogao.autofill.annotation.FillUserInfo;
import com.xiaogao.common.entity.PageData;
import com.xiaogao.common.utils.BeanListUtils;
import com.xiaogao.sys.mapper.SysRoleMapper;
import com.xiaogao.sys.model.SysRole;
import com.xiaogao.sys.model.SysRolePerm;
import com.xiaogao.sys.model.SysUserRole;
import com.xiaogao.sys.request.role.AddParam;
import com.xiaogao.sys.request.role.QueryParam;
import com.xiaogao.sys.request.role.UpdateParam;
import com.xiaogao.sys.response.SysRoleResponse;
import com.xiaogao.sys.service.SysRolePermService;
import com.xiaogao.sys.service.SysRoleService;
import com.xiaogao.sys.service.SysUserRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.lang.String;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@Slf4j
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRolePermService sysRolePermService;

    @FillUserInfo
    @Override
    public PageData<SysRoleResponse> querySelective(Integer pageNum, Integer pageSize, QueryParam queryParam) {
        // 1、先查ids
        LambdaQueryWrapper<SysRole> queryWrapper = getQueryWrapper(queryParam);
        // 分页
        Integer offset = (pageNum - 1) * pageSize;
        queryWrapper.last(String.format("limit %d,%d", offset, pageSize));
        // 只返回id列
        queryWrapper.select(SysRole::getId);
        List<String> ids = sysRoleMapper.selectObjs(queryWrapper);
        // 2、根据ids查询sysRoleResponseList
        List<SysRole> sysRoles = sysRoleMapper.selectByIds(ids);
        List<SysRoleResponse> sysRoleResponses = BeanListUtils.copyList(sysRoles, SysRoleResponse.class);
        // 3、查count
        LambdaQueryWrapper<SysRole> queryCountWrapper = getQueryWrapper(queryParam);
        Long total = sysRoleMapper.selectCount(queryCountWrapper);
        return new PageData<>(sysRoleResponses, total);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    @Override
    public void add(AddParam addParam) {
        // 1、addParam to SysRole
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(addParam, sysRole);
        sysRoleMapper.insert(sysRole);
        // 2、分配权限
        addRolePermRelation(sysRole.getId(), addParam.getPermIds());
    }

    private void addRolePermRelation(String roleId, List<String> ids) {
        if (ids != null && !ids.isEmpty()) {
            List<SysRolePerm> sysRolePerms = new ArrayList<>();
            for (String permId : ids) {
                sysRolePerms.add(new SysRolePerm(roleId, permId));
            }
            sysRolePermService.saveBatch(sysRolePerms);
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    @Override
    public void update(UpdateParam updateParam) {
        // 1、updateParam to SysRole
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(updateParam, sysRole);
        sysRoleMapper.updateById(sysRole);
        // 2、重新分配权限。 2.1 删除权限。  2.2 添加权限
        deleteRolePermRelation(Collections.singletonList(updateParam.getId()));
        addRolePermRelation(sysRole.getId(), updateParam.getPermIds());
    }

    private void deleteRolePermRelation(List<String> roleIds) {
        LambdaQueryWrapper<SysRolePerm> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SysRolePerm::getRoleId, roleIds);
        sysRolePermService.remove(wrapper);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    @Override
    public void delete(List<String> ids) {
        // 1、直接删除角色
        sysRoleMapper.deleteByIds(ids);
        // 2、直接删除角色关联的权限
        deleteRolePermRelation(ids);
    }

    @Override
    public List<String> queryPermIds(String roleId) {
        LambdaQueryWrapper<SysRolePerm> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRolePerm::getRoleId,roleId);
        wrapper.select(SysRolePerm::getPermId);
        return sysRolePermService.listObjs(wrapper);
    }

    @Override
    public List<SysRole> queryByUserId(String userId) {
        LambdaQueryWrapper<SysUserRole> sysUserRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserRoleLambdaQueryWrapper.eq(SysUserRole::getUserId,userId);
        sysUserRoleLambdaQueryWrapper.select(SysUserRole::getRoleId);
        List<String> roleIds = sysUserRoleService.listObjs(sysUserRoleLambdaQueryWrapper);
        if(CollectionUtils.isNotEmpty(roleIds)){
            return sysRoleMapper.selectByIds(roleIds);
        }
        return List.of();
    }

    private LambdaQueryWrapper<SysRole> getQueryWrapper(QueryParam queryParam) {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(queryParam.getCode()), SysRole::getCode, queryParam.getCode());
        queryWrapper.like(StringUtils.isNotEmpty(queryParam.getName()), SysRole::getName, queryParam.getName());
        return queryWrapper;
    }
}
